﻿/* Process 扩展类
 */

/* 未完事项
 * 1、单元测试。
 */
namespace LSLib.Diagnostics
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;

    public class ProcessEx
    {
        /// <summary>以完整的进程路径获取相关的Process数组
        /// </summary>
        /// <param name="procModFileName">关联进程的主模块的完整路径</param>
        /// <returns>System.Diagnostics.Process 类型的数组，它表示运行指定应用程序或文件的进程资源。</returns>
        public static Process[] GetProcessesByFile(string procModFileName)
        {
            if (string.IsNullOrEmpty(procModFileName))
                throw new ArgumentNullException("procModFileName");
            if (File.Exists(procModFileName) == false)
                throw new FileNotFoundException("文件不存在！", procModFileName);

            List<Process> result = new List<Process>();
            string friendlyName = Path.GetFileNameWithoutExtension(procModFileName);

            foreach (Process p in Process.GetProcessesByName(friendlyName))
            {
                try
                {
                    if (p.MainModule.FileName == procModFileName) result.Add(p);
                }
                catch { }
            }
            return result.ToArray();
        }

        #region IsProcessStarted
        /// <summary>检测某进程是否已启动（默认不忽略当前进程）
        /// </summary>
        /// <param name="processName">该进程的友好名称，或者该进程的完整路径</param>
        /// <returns>存在返回true；不存在返回false。</returns>
        public static bool IsProcessStarted(string name)
        {
            return IsProcessStarted(name, false);
        }
        /// <summary>检测某进程是否已启动（可选择是否忽略当前进程）
        /// </summary>
        /// <param name="processName">该进程的友好名称，或者该进程的完整路径</param>
        /// <param name="isIgnoreCurrent">是否忽略当前进程</param>
        /// <returns>存在返回true；不存在返回false。</returns>
        public static bool IsProcessStarted(string name, bool isIgnoreCurrent)
        {
            bool isFile = Path.IsPathRooted(name);

            if (isFile)
                return IsProcessStartedByFile(name, isIgnoreCurrent);
            else
                return IsProcessStartedByName(name, isIgnoreCurrent);
        }

        /// <summary>检测某进程是否已启动（默认不忽略当前进程）
        /// </summary>
        /// <param name="processName">该进程的友好名称</param>
        /// <returns>存在返回true；不存在返回false。</returns>
        public static bool IsProcessStartedByName(string processName)
        {
            return IsProcessStartedByName(processName, false);
        }
        /// <summary>检测某进程是否已启动（可选择是否忽略当前进程）
        /// </summary>
        /// <param name="processName">该进程的友好名称</param>
        /// <param name="isIgnoreCurrent">是否忽略当前进程</param>
        /// <returns>存在返回true；不存在返回false。</returns>
        public static bool IsProcessStartedByName(string processName, bool isIgnoreCurrent)
        {
            string friendlyName = Path.GetFileNameWithoutExtension(processName);
            Process[] procs = Process.GetProcessesByName(friendlyName);
            return isArrayProcessLengthGT0(procs, isIgnoreCurrent);
        }

        /// <summary>检测某进程是否已启动（默认不忽略当前进程）
        /// </summary>
        /// <param name="friendlyName">该进程的完整路径</param>
        /// <returns>存在返回true；不存在返回false。</returns>
        public static bool IsProcessStartedByFile(string procModFileName)
        {
            return IsProcessStartedByFile(procModFileName, false);
        }
        /// <summary>检测某进程是否已启动（可选择是否忽略当前进程）
        /// </summary>
        /// <param name="friendlyName">该进程的完整路径</param>
        /// <param name="isIgnoreCurrent">是否忽略当前进程</param>
        /// <returns>存在返回true；不存在返回false。</returns>
        public static bool IsProcessStartedByFile(string procModFileName, bool isIgnoreCurrent)
        {
            Process[] procs = GetProcessesByFile(procModFileName);
            return isArrayProcessLengthGT0(procs, isIgnoreCurrent);
        }

        private static bool isArrayProcessLengthGT0(Process[] arrayProcess, bool isIgnoreCurrent)
        {
            try
            {
                if (isIgnoreCurrent == false) return arrayProcess.Length > 0;

                //忽略当前进程
                if (arrayProcess.Length == 1)
                {
                    Process curr = Process.GetCurrentProcess();
                    return (arrayProcess[0].Id != curr.Id);
                }
                else { return arrayProcess.Length > 0; }
            }
            catch { return false; }
        }
        #endregion
    }
}
